package me.pcqpcq.android.util;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import me.pcqpcq.android.mgr.ActivityMgr;
import android.app.Activity;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.util.DisplayMetrics;

/**
 * <p>文件信息类</p>
 * <p>包含：文件或目录的相关信息</p>
 * @author pcqpcq
 * @since 2012.02.22
 * @version 0.1
 */
public class FileInfoUtil {
	
	public static final short INFO_TYPE_VERSION = 1;
	public static final short INFO_TYPE_PACKAGE = 2;

	/**
	 * <p>取得指定Apk安装包的相关信息
	 * <p>1. 版本号
	 * <p>2. 包名
	 * @param apkPath Apk路径
	 * @param infoType 信息类型
	 * @return 版本号
	 */
	public static String getApkInfo(String apkPath, int infoType) {
		Activity curActivity = ActivityMgr.getCurActivity();
		// 取得包管理器
		PackageManager pm = curActivity.getPackageManager();
		// 获取包信息
		PackageInfo pi = pm.getPackageArchiveInfo(apkPath, PackageManager.GET_UNINSTALLED_PACKAGES);
		if (pi != null) {
			if (infoType == INFO_TYPE_VERSION) {
				return pi.versionName;
			} else if (infoType == INFO_TYPE_PACKAGE) {
				return pi.packageName;
			} else {
				return "";
			}
		} else
			return "";
	}

	/**
	 * 取得指定Apk安装包中的安装名
	 * @param apkPath 指定Apk路径
	 * @return 安装名
	 */
	public static String getApkInstalledName(String apkPath) {
		String appName = "";
		String PATH_PackageParser = "android.content.pm.PackageParser";
		String PATH_AssetManager = "android.content.res.AssetManager";
		try {
			// 1.1
			// 使用反射机制取得私有类PackageParser的带String参数的构造方法
			// 目标方法为PackageParser packageParser = new PackageParser(apkPath);
			Class<?> pkgParserCls = Class.forName(PATH_PackageParser);
			Class<?>[] typeArgs = new Class[1];
			typeArgs[0] = String.class;
			Constructor<?> pkgParserCt = pkgParserCls.getConstructor(typeArgs);

			// 1.2
			// 向1.1取得的构造方法传递参数
			// 取得apk文件对象
			Object[] valueArgs = new Object[1];
			valueArgs[0] = apkPath;
			Object pkgParser = pkgParserCt.newInstance(valueArgs);

			// 2.1
			// 使用反射机制调用另外一个私有方法
			// PackageParser.Package mPkgInfo = packageParser.parsePackage(new
			// File(apkPath), apkPath, metrics, 0);
			// 取得内部方法
			typeArgs = new Class[4];
			typeArgs[0] = File.class;
			typeArgs[1] = String.class;
			typeArgs[2] = DisplayMetrics.class;
			typeArgs[3] = Integer.TYPE;
			Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod("parsePackage", typeArgs);

			// 2.2
			// 使用1.2取得的对象调用2.1取得的方法，并向它传递参数
			// 取得包信息PackageInfo
			valueArgs = new Object[4];
			valueArgs[0] = new File(apkPath);
			valueArgs[1] = apkPath;
			DisplayMetrics metrics = new DisplayMetrics();
			// 这个参数是与显示有关的, 里面涉及到一些像素显示等等, 我们使用默认的情况
			metrics.setToDefaults();
			valueArgs[2] = metrics;
			valueArgs[3] = 0;
			Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser, valueArgs);

			// 3.1
			// 使用反射机制取得公共类ApplicationInfo中的私有方法
			// 目标方法为ApplicationInfo info = mPkgInfo.applicationInfo;
			// 取得目标程序信息ApplicationInfo
			Field appInfoFld = pkgParserPkg.getClass().getDeclaredField("applicationInfo");
			ApplicationInfo info = (ApplicationInfo) appInfoFld.get(pkgParserPkg);

			if (info.labelRes != 0) {
				// 4.1
				// 与1.1类似使用反射调用AssetManager类的内部方法
				// 原始方法为：
				// Resources pRes = getResources();
				// AssetManager assmgr = new AssetManager();
				// assmgr.addAssetPath(apkPath);
				// Resources res = new Resources(assmgr, pRes.getDisplayMetrics(),
				// pRes.getConfiguration());
				// 取得apk安装包内的资源
				Class<?> assetMgrCls = Class.forName(PATH_AssetManager);
				Constructor<?> assetMgrCt = assetMgrCls.getConstructor((Class[]) null);

				Object assetMgr = assetMgrCt.newInstance((Object[]) null);
				typeArgs = new Class[1];
				typeArgs[0] = String.class;
				Method assetMgr_addAssetPathMtd = assetMgrCls.getDeclaredMethod("addAssetPath", typeArgs);

				valueArgs = new Object[1];
				valueArgs[0] = apkPath;
				assetMgr_addAssetPathMtd.invoke(assetMgr, valueArgs);

				Activity curActivity = ActivityMgr.getCurActivity();
				Resources res = curActivity.getResources();
				typeArgs = new Class[3];
				typeArgs[0] = assetMgr.getClass();
				typeArgs[1] = res.getDisplayMetrics().getClass();
				typeArgs[2] = res.getConfiguration().getClass();
				Constructor<?> resCt = Resources.class.getConstructor(typeArgs);

				valueArgs = new Object[3];
				valueArgs[0] = assetMgr;
				valueArgs[1] = res.getDisplayMetrics();
				valueArgs[2] = res.getConfiguration();
				res = (Resources) resCt.newInstance(valueArgs);
				
				// 5.1
				// 使用4.1的资源取得目标信息（图标，名称，包名等）
				appName = res.getText(info.labelRes).toString();
			} else if (info.nonLocalizedLabel != null) {
				appName = info.nonLocalizedLabel.toString();
			}
		} catch (Exception e) {
			e.getMessage();
		}
		return appName;
	}

}
